/***********************************************************************
 *            Project: CoreCms
 *        ProjectName: 核心内容管理系统                                
 *                Web: https://www.corecms.net                      
 *             Author: 大灰灰                                          
 *              Email: jianweie@163.com                                
 *         CreateTime: 2021/1/31 21:45:10
 *        Description: 暂无
 ***********************************************************************/

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using CoreCms.Net.Configuration;
using CoreCms.Net.IRepository;
using CoreCms.Net.IRepository.UnitOfWork;
using CoreCms.Net.IServices;
using CoreCms.Net.Loging;
using CoreCms.Net.Model.Entities;
using CoreCms.Net.Model.Entities.Expression;
using CoreCms.Net.Model.ViewModels.UI;
using CoreCms.Net.Model.ViewModels.DTO;
using CoreCms.Net.Utility.Extensions;
using CoreCms.Net.Utility.Helper;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Hosting;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using SqlSugar;
using CoreCms.Net.Model.FromBody;
using static CoreCms.Net.Configuration.GlobalEnumVars;
using static SKIT.FlurlHttpClient.Wechat.Api.Models.WxaGetWxaGameFrameResponse.Types.Data.Types.Frame.Types;
using Org.BouncyCastle.Crypto;
using System.Linq.Expressions;
using NPOI.SS.Formula.Functions;
using static SKIT.FlurlHttpClient.Wechat.Api.Models.CgibinExpressDeliveryOpenMessageFollowWaybillRequest.Types;
using static SKIT.FlurlHttpClient.Wechat.Api.Models.ComponentTCBDbIndexRequest.Types;

namespace CoreCms.Net.Services
{
    /// <summary>
    /// 购物车表 接口实现
    /// </summary>
    public class CoreCmsCartServices : BaseServices<CoreCmsCart>, ICoreCmsCartServices
    {
        private readonly ICoreCmsCartRepository _dal;

        private readonly ICoreCmsGoodsCollectionServices _goodsCollectionServices;
        private readonly ICoreCmsPinTuanRuleServices _pinTuanRuleServices;
        private readonly ICoreCmsShipServices _shipServices;
        private readonly ICoreCmsPromotionServices _promotionServices;
        private readonly ICoreCmsPromotionConditionServices _promotionConditionServices;
        private readonly ICoreCmsPromotionResultServices _promotionResultServices;
        private readonly ICoreCmsCouponServices _couponServices;
        private readonly ICoreCmsUserServices _userServices;
        private readonly ICoreCmsSettingServices _settingServices;
        private readonly IServiceProvider _serviceProvider;
        private readonly ICoreCmsProductsServices _productsServices;
        private readonly ICoreCmsPinTuanGoodsServices _pinTuanGoodsServices;
        private readonly ICoreCmsPinTuanRecordServices _pinTuanRecordServices;
        private readonly ICoreCmsGoodsServices _goodsServices;
        private readonly ICoreCmsGoodsCategoryServices _goodsCategoryServices;

        public CoreCmsCartServices(
            ICoreCmsCartRepository dal
            , IServiceProvider serviceProvider
            , ICoreCmsGoodsCollectionServices goodsCollectionServices
            , ICoreCmsPinTuanRuleServices pinTuanRuleServices
            , ICoreCmsShipServices shipServices
            , ICoreCmsPromotionServices promotionServices
            , ICoreCmsCouponServices couponServices
            , ICoreCmsUserServices userServices
            , ICoreCmsSettingServices settingServices
            , ICoreCmsProductsServices productsServices
            , ICoreCmsPinTuanGoodsServices pinTuanGoodsServices, ICoreCmsPromotionConditionServices promotionConditionServices, ICoreCmsGoodsServices goodsServices, ICoreCmsGoodsCategoryServices goodsCategoryServices, ICoreCmsPromotionResultServices promotionResultServices, ICoreCmsPinTuanRecordServices pinTuanRecordServices)
        {
            this._dal = dal;
            base.BaseDal = dal;

            _serviceProvider = serviceProvider;
            _goodsCollectionServices = goodsCollectionServices;
            _pinTuanRuleServices = pinTuanRuleServices;
            _shipServices = shipServices;
            _promotionServices = promotionServices;
            _couponServices = couponServices;
            _userServices = userServices;
            _settingServices = settingServices;
            _productsServices = productsServices;
            _pinTuanGoodsServices = pinTuanGoodsServices;
            _promotionConditionServices = promotionConditionServices;
            _goodsServices = goodsServices;
            _goodsCategoryServices = goodsCategoryServices;
            _promotionResultServices = promotionResultServices;
            _pinTuanRecordServices = pinTuanRecordServices;
        }


        /// <summary>
        /// 添加多个货品到购物车
        /// </summary>
        /// <param name="userId">用户id</param>
        /// <param name="productId">货品序号</param>
        /// <param name="nums">数量</param>
        /// <param name="numType">数量类型/1是直接增加/2是赋值</param>
        /// <param name="cartTypes">1=普通，2=拼团，3=团购，4=秒杀，6=砍价，7=赠品，8=接龙，9=订货会，</param>
        /// <param name="objectId">关联对象类型</param>
        /// <returns></returns>
        public async Task<WebApiCallBack> Add(int userId, List<FMCartAddItem> additems, AddCartType numType, int goodsid, OrderType cartTypes, int objectId = 0)
        {
            var jm = new WebApiCallBack();



            if (additems == null && additems.Count == 0)
            {
                jm.msg = "请选择货品";
                return jm;
            }

            using var container = _serviceProvider.CreateScope();

            var orderServices = container.ServiceProvider.GetService<ICoreCmsOrderServices>();
            var productsServices = container.ServiceProvider.GetService<ICoreCmsProductsServices>();
            var goodsServices = container.ServiceProvider.GetService<ICoreCmsGoodsServices>();
            var meetingGoodsServices = container.ServiceProvider.GetService<ICoreShopOrderMeetingGoodsServices>();


            #region  初始化  goods,carts,meetinggood
            CoreCmsGoods goods = await goodsServices.QueryByClauseAsync(m => m.id == goodsid);
            CoreShopOrderMeetingGoods meetinggood = null;
            var carts = _dal.GetDb().Queryable<CoreCmsProducts>()
       .In(additems.Select(a => a.ProductId)).Select(m => new CoreCmsCart()
       {
           goodsId = m.goodsId,
           isSelect = true,
           nums = 0,
           objectId = objectId,
           type = (int)cartTypes,
           productId = m.id,
           userId = userId,
           product = m,


       }).ToList();
            foreach (var cart in carts)
            {
                cart.nums = additems.Find(m => m.ProductId == cart.productId).Nums;
            }

            #region 根据购物车存储类型匹配数据, 
            switch (cartTypes)
            {
                case GlobalEnumVars.OrderType.Common:
                    //标准模式不需要做什么判断
                    break;
                case GlobalEnumVars.OrderType.Meeting:
                    meetinggood = await meetingGoodsServices.QueryByClauseAsync(m => m.meetingid == objectId && m.goodid == goodsid);
                    //购物车并 不用价格
                    //foreach (var cart in carts)
                    //{
                    //    cart.product.price = meetinggood.meetingprice;
                    //    cart.goods.price = meetinggood.meetingprice;
                    //}

                    break;


                case GlobalEnumVars.OrderType.Group or GlobalEnumVars.OrderType.Skill:

                    break;
                case GlobalEnumVars.OrderType.Bargain:

                    break;

                case GlobalEnumVars.OrderType.Solitaire:

                    break;
                default:

                    break;
            }
            #endregion


            #endregion

            #region  判断product信息，检查下架， 检查起订量， 库存，
            if (cartTypes != GlobalEnumVars.OrderType.Meeting && !goods.isMarketable)
            {
                jm.msg = "已下架";
                return jm;
            }
            if (additems.Sum(m => m.Nums) < (meetinggood == null ? goods.minimum : meetinggood.meetingminimum))
            {
                jm.msg = "未到起订量";
                return jm;
            }
            var nostocks = carts.Where(m => m.nums > m.product.stock).ToList();
            if (nostocks.Count > 0)
            {
                jm.msg = "库存不足";
                jm.data = nostocks.Select(m => new FMCartAddItem
                {
                    canBuyNum = m.product.stock,
                    Nums = m.nums,
                    ProductId = m.productId
                });
                return jm;
            }

            #endregion

            #region 再进行购物车数据库操作
            List<int> reslist = new List<int>();
            foreach (var item in carts)
            {

                var cattInfo = await _dal.QueryByClauseAsync(p => p.userId == userId && p.type==(int) cartTypes && p.objectId == objectId && p.productId == item.productId);
                if (cattInfo != null)
                {
                    item.id = cattInfo.id;
                    reslist.Add(cattInfo.id);
                }


            }
            BaseDal.GetDb().Updateable(carts.Where(m => m.id != 0).ToList()).UpdateColumns(m => m.nums).ExecuteCommand();
            var addlist = BaseDal.GetDb().Insertable(carts.Where(m => m.id == 0).ToList()).ExecuteReturnPkList<int>();

            reslist.AddRange(addlist);
            reslist.Remove(0);
            #endregion

            jm.data = reslist;
            jm.msg = "添加成功";
            jm.status = true;
            return jm;

        }
        /// <summary>
        /// 结算信息获取。
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="ids"></param>
        /// <param name="areaId"></param>
        /// <param name="freightId"></param>
        /// <param name="packageId"></param>
        /// <param name="invoice"></param>
        /// <returns></returns>
        public async Task<WebApiCallBack> GetCartInfosXL(int userId, int[] ids, int areaId, List<FMCartAddItem> editlist,
            int freightId = 0, int packageId = 0, int invoice = 0)
        {
            var jm = new WebApiCallBack() { methodDescription = "获取下单结算信息" };
            using var container = _serviceProvider.CreateScope();
            var productsService = container.ServiceProvider.GetService<ICoreCmsProductsServices>();
            var goodsServices = container.ServiceProvider.GetService<ICoreCmsGoodsServices>();
            var shipServices = container.ServiceProvider.GetService<ICoreCmsShipServices>();
            var meetingGoodServices = container.ServiceProvider.GetService<ICoreShopOrderMeetingGoodsServices>();

            #region 初始化  goods,carts,meetinggood
            var carts = _dal.GetDb().Queryable<CoreCmsCart>()
             .In(ids)
                    .Includes(t => t.goods)
             .Includes(t => t.product, prd => prd.color)
             .Includes(t => t.product, prd => prd.size).ToList();
            //查询购物车商品信息

            if (carts.Count == 0)
            {
                jm.msg = "购物车失效";
                return jm;
            }
            CoreCmsGoods goods = await goodsServices.QueryByClauseAsync(m => m.id == carts.First().goodsId);
            CoreShopOrderMeetingGoods meetinggood = null;
            var cartTypes = (OrderType)carts.First().type;
            var objectId = carts.First().objectId;
            var goodsid = carts.First().goodsId;
            #endregion


            #region 根据购物车存储类型匹配数据
            switch (cartTypes)
            {
                case GlobalEnumVars.OrderType.Common:
                    foreach (var cart in carts)
                    {
                        cart.price = cart.product.price;

                    }
                    //标准模式不需要做什么判断
                    break;
                case GlobalEnumVars.OrderType.Meeting:
                    meetinggood = await meetingGoodServices.QueryByClauseAsync(m => m.meetingid == objectId && m.goodid == goodsid);
                    foreach (var cart in carts)
                    {
                        cart.price = meetinggood.meetingprice;

                        cart.product.price = meetinggood.meetingprice;


                    }

                    break;


                case GlobalEnumVars.OrderType.Group or GlobalEnumVars.OrderType.Skill:

                    break;
                case GlobalEnumVars.OrderType.Bargain:

                    break;

                case GlobalEnumVars.OrderType.Solitaire:

                    break;
                default:

                    break;
            }
            #endregion

            #region 修改数量
            List<CoreCmsCart> updateList = new List<CoreCmsCart>();
            if (editlist != null)
            {
              
                foreach (var editItem in editlist)
                {
                    carts.First(m => m.id == editItem.id).nums = editItem.Nums;

                    updateList.Add(carts.First(m => m.id == editItem.id));
                  
                }
            
               

            }
            #endregion


            #region  判断product信息，检查下架， 检查起订量， 库存，
            if (cartTypes != GlobalEnumVars.OrderType.Meeting && !goods.isMarketable)
            {
                jm.msg = "已下架";
                return jm;
            }
            if (carts.Sum(m => m.nums) < (meetinggood == null ? goods.minimum : meetinggood.meetingminimum))
            {
                jm.msg = "未到起订量";
                return jm;
            }
            var nostocks = carts.Where(m => m.nums > m.product.stock && m.product.stock>0).ToList();
            if (nostocks.Count > 0)
            {
                jm.msg = "库存不足";
                jm.data = nostocks.Select(m => new FMCartAddItem
                {
                    canBuyNum = m.product.stock,
                    Nums = m.nums,
                    ProductId = m.productId
                });
                return jm;
            }

            #endregion

            GetDb().Updateable(updateList).UpdateColumns(m => m.nums).ExecuteCommand();

            //返回实体。
            var cartDotXL = new CartDotXL();
            cartDotXL.colorList = new List<CartDotColorXL>();
            cartDotXL.bn = goods.bn;
            #region 颜色colorList

            var colorgroup = carts.GroupBy(m => m.product.color.value);
            foreach (var item in colorgroup)
            {

                var newcolorgroup = new CartDotColorXL()
                {
                    colorId = item.First().product.colorId,
                    color = item.Key,
                    price = item.First().product.price,
                    prodList = new List<FMSetCartNum>(),
                    sn = item.First().product.sn,
                    imageurl = item.First().product.images,
                };
                foreach (var subitem in item)
                {
                    var nepro = new FMSetCartNum()
                    {
                        stock = subitem.product.stock,
                        productId = subitem.productId, //这里注意这里的id是
                        size = subitem.product.size.value,
                        nums = subitem.nums,
                        cartId = subitem.id,
                        select = true,
                    };
                    newcolorgroup.prodList.Add(nepro);
                }
                //循环获取颜色下面的prod（尺码）
                cartDotXL.colorList.Add(newcolorgroup);
            }
            #endregion


            #region  费用计算 costList
            cartDotXL.costFreight = await CostFreight(carts, areaId, freightId);
            cartDotXL.costPackage = await CostPackage(carts, packageId);
            cartDotXL.goodsAmount = carts.Sum(m => m.price * m.nums);
            #endregion

            #region 减少费用计算
            #endregion

            #region 发票
            #endregion


            //总费用
            cartDotXL.orderAmount = cartDotXL.goodsAmount;
            cartDotXL.orderAmount += cartDotXL.costFreight.select.amount;
            cartDotXL.orderAmount += cartDotXL.costPackage.select.amount;


            jm.status = true;
            jm.data = cartDotXL;
            jm.otherData = carts;//给提交订单用
            return jm;

        }


        /// <summary>
        /// 购物车信息查询和修改
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="selectids"></param>
        /// <param name="areaId"></param>
        /// <param name="freightId"></param>
        /// <param name="packageId"></param>
        /// <param name="invoice"></param>
        /// <returns></returns>
        public async Task<WebApiCallBack> GetCartInfosXLAll(int userId, int[] selectids, int areaId, List<FMCartAddItem> editlist,
            int freightId = 0, int packageId = 0, int invoice = 0)
        {
            using var container = _serviceProvider.CreateScope();
            var meetingGoodServices = container.ServiceProvider.GetService<ICoreShopOrderMeetingGoodsServices>();
            var meetingServices = container.ServiceProvider.GetService<ICoreShopOrderMeetingServices>();
            var brandServices= container.ServiceProvider.GetService<ICoreCmsBrandServices>();
            var jm = new WebApiCallBack() { methodDescription = "获取购物车信息" };
            //返回实体。实例化
            var cartDotXLAll = new CartDotXLALl();
            cartDotXLAll.groupList = new List<CartDotAllXL>();

            //查询购物车商品信息
            var carts = _dal.GetDb().Queryable<CoreCmsCart>()
                .Where(m => m.userId == userId)
                .Includes(t => t.goods)
                .Includes(t => t.product, prd => prd.color)
                .Includes(t => t.product, prd => prd.size).ToList();
            if (carts.Count() == 0)
            {
                jm.status = true;
                jm.data = cartDotXLAll;
                return jm;
            }
            // 选择项
            for (int index = 0; index < carts.Count(); index++)
            {
                carts[index].isSelect = selectids.Contains(carts[index].id);
            }
            //修改数量
            List<CoreCmsCart> updateList = new List<CoreCmsCart>();
            if (editlist != null)
            {

                foreach (var editItem in editlist)
                {
                    carts.First(m => m.id == editItem.id).nums = editItem.Nums;

                    updateList.Add(carts.First(m => m.id == editItem.id));

                }



            }

            #region  分组group
            //var gcartsFirst = carts.GroupBy(m => m.type + ":" + m.objectId).ToList();
            //foreach (var itemFirst in gcartsFirst)
            //{
            //    var cartTypes = (OrderType)int.Parse(itemFirst.Key.Split(':')[0]);
            //    var objectId = int.Parse(itemFirst.Key.Split(':')[1]); //不同的品牌或者订货会
            //    var objgroup = new CartDotAllXL()
            //    {
            //        objectId = objectId,
            //        orderType =(int) cartTypes,
            //        groupName =   "品牌或者订货会名",
            //        bnList = new List<BnGroup>(),
            //    };
            //    //二级。 bn 分组
            //    var goodGroup = itemFirst.GroupBy(m => m.goodsId);
            //    foreach (var cartlist in goodGroup) //不同的goodsid
            //    {
            //        var bn = new BnGroup()
            //        {
            //            productId = cartlist.Key,
            //            bn = cartlist.First().goods.bn,
            //            colorList = new List<CartDotColorXL>(),
            //        };
            //        int[] ids=   cartlist.Select(m => m.id).ToList().ToArray();
            //        var jmo= ( await  GetCartInfosXL(userId, ids, areaId, null, freightId, packageId, invoice));
            //        var  cardota= (CartDotXL)jmo.data;
            //        bn.colorList = cardota.colorList;
            //        objgroup.bnList.Add(bn);
            //    }
            //    cartDotXLAll.groupList.Add(objgroup);
            //}

            #endregion



            #region groupList

            var group = carts.GroupBy(m => m.type + ":" + m.objectId).ToList();
        
            foreach (var itemFirst in group) //一级 品牌 或者订货会
            {
                var cartTypes = (OrderType)int.Parse(itemFirst.Key.Split(':')[0]);
                var objectId = int.Parse(itemFirst.Key.Split(':')[1]); //不同的品牌或者订货会
                CoreShopOrderMeetingGoods meetinggood = null;
                string groupName = "";
                if (cartTypes == GlobalEnumVars.OrderType.Meeting)
                {
                    groupName = meetingServices.QueryById(objectId).name;
                }

                if (cartTypes == GlobalEnumVars.OrderType.Common)
                {
                    groupName = brandServices.QueryById(objectId).name;
                }

                var objgroup = new CartDotAllXL()
                {
                    objectId = objectId,
                    orderType = (int)cartTypes,
                    groupName = groupName,
                    bnList = new List<BnGroup>(),
                };
                //二级。 bn 分组
                var bnGroup = itemFirst.GroupBy(m => m.goodsId);
                foreach (var bnitem in bnGroup)
                {
                    var bn = new BnGroup()
                    {
                        productId = bnitem.First().goodsId,
                        bn = bnitem.First().goods.bn,
                        colorList = new List<CartDotColorXL>(),
                    };

                    //三级 颜色分组
                    var colorGroup = bnitem.GroupBy(m => m.product.color.value);
                    var product = bnitem.First().product;
                    var goods = bnitem.First().goods;
                    if (cartTypes == GlobalEnumVars.OrderType.Meeting)
                    {
                        meetinggood = await meetingGoodServices.QueryByClauseAsync(m => m.meetingid == objectId && m.goodid == product.goodsId);
                    }
                    foreach (var coloritem in colorGroup)
                    {
                        #region  判断product信息，检查下架， 检查起订量， 库存，
                        //if (cartTypes != GlobalEnumVars.OrderType.Meeting && !goods.isMarketable)
                        //{
                        //    jm.msg = "已下架";
                        //    return jm;
                        //}
                        //if (coloritem.Sum(m => m.nums) < (meetinggood == null ? goods.minimum : meetinggood.meetingminimum))
                        //{
                        //    jm.msg = "未到起订量";
                        //    return jm;
                        //}
                        //var nostocks = coloritem.Where(m => m.nums > m.product.stock).ToList();
                        //if (nostocks.Count > 0)
                        //{
                        //    jm.msg = "库存不足";
                        //    jm.data = nostocks.Select(m => new FMCartAddItem
                        //    {
                        //        canBuyNum = m.product.stock,
                        //        Nums = m.nums,
                        //        ProductId = m.productId
                        //    });
                        //    return jm;
                        //}

                        #endregion

                        var newcolorgroup = new CartDotColorXL()
                        {
                            colorId = coloritem.First().product.colorId,
                            color = coloritem.Key,
                            price = (meetinggood == null ? product.price : meetinggood.meetingprice),
                            prodList = new List<FMSetCartNum>(),
                            sn = coloritem.First().product.sn,
                            imageurl = coloritem.First().product.images,


                        };
                        //四级 颜色分组
                        foreach (var subsubitem in coloritem)
                        {
                            subsubitem.price = (meetinggood == null ? product.price : meetinggood.meetingprice);
                            //subsubitem.product.price= (meetinggood == null ? goods.price : meetinggood.meetingprice);
                            var nepro = new FMSetCartNum()
                            {
                                productId = subsubitem.productId, //这里注意这里的id是
                                size = subsubitem.product.size.value,
                                nums = subsubitem.nums,
                                cartId = subsubitem.id,
                                select = selectids.Contains(subsubitem.id),

                                stock = subsubitem.product.stock,

                            };
                            newcolorgroup.prodList.Add(nepro);
                        }
                     
                     
                        bn.colorList.Add(newcolorgroup);
                    }


                    objgroup.bnList.Add(bn);
                }

                cartDotXLAll.groupList.Add(objgroup);
            }
            #endregion
            GetDb().Updateable(updateList).UpdateColumns(m => m.nums).ExecuteCommand();
            //计算价格

            cartDotXLAll.goodsAmount = carts.Where(c => c.isSelect).Sum(c => c.price * c.nums);
            if (cartDotXLAll.goodsAmount > 0)
            {
                cartDotXLAll.costFreight = (await CostFreight(carts.Where(m => m.isSelect).ToList(), areaId, freightId));

                cartDotXLAll.costPackage = await CostPackage(carts.Where(m=>m.isSelect).ToList(), packageId);
                cartDotXLAll.orderAmount = cartDotXLAll.goodsAmount + 
                    cartDotXLAll.costPackage.select.amount +
                    cartDotXLAll.costFreight.select.amount;


            }







            jm.status = true;
            jm.data = cartDotXLAll;
            jm.otherData = carts;
            return jm;

        }



        //public async Task<WebApiCallBack> GetCartInfosXLAll(int userId, int[] selectids, int areaId, List<FMCartAddItem> editlist,
        // int freightId = 0, int packageId = 0, int invoice = 0)
        //{
        //    var jm = new WebApiCallBack() { methodDescription = "获取购物车信息" };
        //    using var container = _serviceProvider.CreateScope();
        //    var productsService = container.ServiceProvider.GetService<ICoreCmsProductsServices>();
        //    var goodsServices = container.ServiceProvider.GetService<ICoreCmsGoodsServices>();

        //    var meetingGoodServices = container.ServiceProvider.GetService<ICoreShopOrderMeetingGoodsServices>();

        //    //查询  ListCart  修改， 并且查询订货会价格以及起订量
        //    //ListCart 判断product信息，检查下架， 检查起订量，最后判断库存，
        //    // 写入数据库修改


        //    //查询购物车商品信息
        //    var carts = _dal.GetDb().Queryable<CoreCmsCart>()
        //        .Where(m => m.userId == userId)
        //        .Includes(t => t.goods)
        //        .Includes(t => t.product, prd => prd.color)
        //        .Includes(t => t.product, prd => prd.size).ToList();
        //    //返回实体。
        //    var cartDotXLAll = new CartDotXLALl();
        //    cartDotXLAll.groupList = new List<CartDotAllXL>();

        //    if (carts.Count() == 0)
        //    {
        //        jm.status = true;
        //        jm.data = cartDotXLAll;
        //        return jm;
        //    }
        //    // 选择项
        //    for (int index = 0; index < carts.Count(); index++)
        //    {
        //        carts[index].isSelect = selectids.Contains(carts[index].id);
        //    }


        //    #region 修改数量

        //    if (editlist != null)
        //    {
        //        List<CoreCmsCart> updateList = carts;
        //        foreach (var editItem in editlist)
        //        {
        //            updateList.First(m => m.id == editItem.id).nums = editItem.Nums;
        //        }

        //        carts = updateList;
        //    }

        //    #endregion

        //    #region groupList

        //    var group = carts.GroupBy(m => m.objectId);
        //    foreach (var item in group) //一级 品牌 或者订货会
        //    {
        //        var objgroup = new CartDotAllXL()
        //        {
        //            objectId = item.Key,
        //            orderType = item.First().type,
        //            groupName = item.Key + "品牌或者订货会名",
        //            bnList = new List<BnGroup>(),
        //        };
        //        //二级。 bn 分组
        //        var bnGroup = item.GroupBy(m => m.goods.bn);
        //        foreach (var bnitem in bnGroup)
        //        {
        //            var bn = new BnGroup()
        //            {
        //                productId = bnitem.First().goodsId,
        //                bn = bnitem.Key,
        //                colorList = new List<CartDotColorXL>(),
        //            };

        //            //三级 颜色分组
        //            var colorGroup = bnitem.GroupBy(m => m.product.color.value);
        //            foreach (var coloritem in colorGroup)
        //            {
        //                var newcolorgroup = new CartDotColorXL()
        //                {
        //                    colorId = coloritem.First().product.colorId,
        //                    color = coloritem.Key,
        //                    price = coloritem.First().product.price,
        //                    prodList = new List<FMSetCartNum>(),
        //                    sn = coloritem.First().product.sn,
        //                    imageurl = coloritem.First().product.images,


        //                };
        //                //四级 颜色分组
        //                foreach (var subsubitem in coloritem)
        //                {
        //                    var nepro = new FMSetCartNum()
        //                    {
        //                        productId = subsubitem.productId, //这里注意这里的id是
        //                        size = subsubitem.product.size.value,
        //                        nums = subsubitem.nums,
        //                        cartId = subsubitem.id,
        //                        select = selectids.Contains(subsubitem.id),
        //                        stock = subsubitem.product.stock,

        //                    };
        //                    newcolorgroup.prodList.Add(nepro);
        //                }

        //                bn.colorList.Add(newcolorgroup);
        //            }


        //            objgroup.bnList.Add(bn);
        //        }

        //        cartDotXLAll.groupList.Add(objgroup);
        //    }
        //    #endregion

        //    #region group结束了在进行检测，不管修不修改都进行检测，因为购物车库存可能没了
        //    foreach (var item in cartDotXLAll.groupList)
        //    {
        //        var type = (OrderType)item.orderType;
        //        var objid = item.objectId;
        //        foreach (var bnitem in item.bnList)
        //        {
        //            var goodsid = bnitem.productId;
        //            if (!await CheckMinimum(type, objid, goodsid, bnitem.colorList, meetingGoodServices, goodsServices))
        //            {
        //                jm.msg = "未到起订量";
        //                return jm;
        //            }
        //        }
        //    }

        //    var slist = await CheckStock(carts);
        //    if (slist.Count() > 0)
        //    {
        //        jm.msg = "库存不足";
        //        jm.data = slist;
        //        return jm;
        //    }


        //    #endregion
        //    //数据库更新数量
        //    if (editlist != null)
        //    {
        //        GetDb().Updateable(carts).UpdateColumns(it => new { it.nums }).ExecuteCommand();
        //    }


        //    cartDotXLAll.goodsAmount = await CalcGoodsAmount(carts);
        //    cartDotXLAll.orderAmount = cartDotXLAll.goodsAmount;
        //    #region  费用计算 cost
        //    if (cartDotXLAll.goodsAmount > 0)
        //    {
        //        cartDotXLAll.costFreight = await CostFreight(carts, areaId, freightId);
        //        cartDotXLAll.costPackage = await CostPackage(carts, packageId);
        //        cartDotXLAll.orderAmount += cartDotXLAll.costFreight.select.amount;
        //        cartDotXLAll.orderAmount += cartDotXLAll.costPackage.select.amount;
        //    }


        //    #endregion

        //    #region 减少费用计算
        //    #endregion

        //    #region 发票

        //    #endregion

        //    #region 库存检查

        //    #endregion









        //    jm.status = true;
        //    jm.data = cartDotXLAll;
        //    return jm;

        //}



        #region 设置购物车商品数量====================================================

        /// <summary>
        /// 设置购物车商品数量
        /// </summary>
        /// <param name="id"></param>
        /// <param name="nums"></param>
        /// <param name="userId"></param>
        /// <param name="numType"></param>
        /// <param name="type"></param>
        /// <returns></returns>
        public async Task<WebApiCallBack> SetCartNum(int id, int nums, int userId, int numType, int type = 1)
        {
            var jm = new WebApiCallBack();

            if (userId == 0)
            {
                jm.msg = "用户信息获取失败";
                return jm;
            }
            if (id == 0)
            {
                jm.msg = "请提交要设置的信息";
                return jm;
            }
            var cartModel = await _dal.QueryByClauseAsync(p => p.userId == userId && p.productId == id);
            if (cartModel == null)
            {
                jm.msg = "获取购物车数据失败";
                return jm;
            }
            //var outData = await Add(userId, cartModel.productId, nums, numType, type);
            //jm.status = outData.status;
            //jm.msg = jm.status ? GlobalConstVars.SetDataSuccess : GlobalConstVars.SetDataFailure;
            //jm.otherData = outData;

            return jm;
        }


        #endregion

        #region  重写删除指定ID集合的数据(批量删除)
        /// <summary>
        /// 重写删除指定ID集合的数据(批量删除)
        /// </summary>
        /// <param name="ids"></param>
        /// <param name="userId"></param>
        /// <returns></returns>
        public async Task<WebApiCallBack> DeleteByIdsAsync(int id, int userId)
        {
            var jm = new WebApiCallBack();

            if (userId == 0)
            {
                jm.msg = "用户信息获取失败";
                return jm;
            }
            if (id <= 0)
            {
                jm.msg = "请提交要删除的货品";
                return jm;
            }
            jm.status = await _dal.DeleteAsync(p => p.id == id && p.userId == userId);
            jm.msg = jm.status ? "删除成功" : "删除失败";

            return jm;
        }
        #endregion

     
       

        #region 在加入购物车的时候，判断是否有参加拼团的商品

        /// <summary>
        /// 在加入购物车的时候，判断是否有参加拼团的商品
        /// </summary>
        /// <param name="productId"></param>
        /// <param name="userId">用户序列</param>
        /// <param name="nums">加入购物车数量</param>
        /// <param name="teamId">团队序列</param>
        public async Task<WebApiCallBack> AddCartHavePinTuan(int productId, int userId = 0, int nums = 1, int teamId = 0)
        {
            var jm = new WebApiCallBack();
            var products = await _productsServices.QueryByIdAsync(productId);
            if (products == null)
            {
                jm.data = 10000;
                jm.msg = GlobalErrorCodeVars.Code10000;
                return jm;
            }
            var pinTuanGoods = await _pinTuanGoodsServices.QueryByClauseAsync(p => p.goodsId == products.goodsId);
            if (pinTuanGoods == null)
            {
                jm.data = 10000;
                jm.msg = GlobalErrorCodeVars.Code10000;
                return jm;
            }
            var pinTuanRule = await _pinTuanRuleServices.QueryByClauseAsync(p => p.id == pinTuanGoods.ruleId);
            if (pinTuanRule == null)
            {
                jm.data = 10000;
                jm.msg = GlobalErrorCodeVars.Code10000;
                return jm;
            }

            if (pinTuanRule.startTime > DateTime.Now)
            {
                jm.data = 15601;
                jm.msg = GlobalErrorCodeVars.Code15601;
                return jm;
            }
            if (pinTuanRule.endTime < DateTime.Now)
            {
                jm.data = 15602;
                jm.msg = GlobalErrorCodeVars.Code15602;
                return jm;
            }
            //查询是否存在已经开团，并且自己是队长的拼团
            var havaGroup = await _pinTuanRecordServices.ExistsAsync(p =>
                p.id == p.teamId
                && p.userId == userId
                && p.goodsId == products.goodsId
                && p.teamId == teamId
                && p.status == (int)GlobalEnumVars.PinTuanRecordStatus.InProgress);
            if (havaGroup)
            {
                jm.data = 15613;
                jm.msg = GlobalErrorCodeVars.Code15613;
                return jm;
            }

            using var container = _serviceProvider.CreateScope();
            var orderRepository = container.ServiceProvider.GetService<ICoreCmsOrderRepository>();
            var checkOrder = orderRepository.FindLimitOrder(products.id, userId, pinTuanRule.startTime, pinTuanRule.endTime, (int)GlobalEnumVars.OrderType.PinTuan);
            if (pinTuanRule.maxGoodsNums > 0)
            {
                if (checkOrder.TotalOrders + nums > pinTuanRule.maxGoodsNums)
                {
                    jm.data = 15610;
                    jm.msg = GlobalErrorCodeVars.Code15610;
                    return jm;
                }
            }
            if (pinTuanRule.maxNums > 0)
            {
                if (checkOrder.TotalUserOrders > pinTuanRule.maxNums)
                {
                    jm.data = 15611;
                    jm.msg = GlobalErrorCodeVars.Code15611;
                    return jm;
                }
            }

            jm.status = true;
            return jm;
        }


        #endregion

        #region 获取购物车原始列表(未核算)

        /// <summary>
        /// 获取购物车原始列表(未核算)
        /// </summary>
        /// <param name="userId">用户序号</param>
        /// <param name="ids">已选择货号</param>
        /// <param name="type">购物车类型/同订单类型</param>
        /// <param name="objectId">关联非订单类型数据序列</param>
        /// <returns></returns>
        public async Task<WebApiCallBack> GetCartDtoData(int userId, int[] ids  , int type, int objectId = 0)
        {
            var jm = new WebApiCallBack() { methodDescription = "获取购物车原始列表(未核算)" };

            using var container = _serviceProvider.CreateScope();
            var productsService = container.ServiceProvider.GetService<ICoreCmsProductsServices>();
            var goodsServices = container.ServiceProvider.GetService<ICoreCmsGoodsServices>();


            var carts = await _dal.QueryListByClauseAsync(p => p.userId == userId && p.type == type, p => p.id, OrderByType.Asc);
            var cartDto = new CartDto { userId = userId, type = type };

            foreach (var item in carts)
            {
                var cartProducts = new CartProducts();
                //如果没有此商品，就在购物车里删掉
                var productInfo = await productsService.GetProductInfo(item.productId, false, userId);
                if (productInfo == null)
                {
                    await _dal.DeleteAsync(item);
                    continue;
                }
                //商品下架，就从购物车里面删除
                var ps = await productsService.GetShelfStatus(item.productId);
                if (ps == false)
                {
                    await _dal.DeleteAsync(item);
                    continue;
                }
                //获取重量
                var goodsWeight = await goodsServices.GetWeight(item.productId);

                //开始赋值
                cartProducts.id = item.id;
                cartProducts.userId = userId;
                cartProducts.productId = item.productId;
                cartProducts.nums = item.nums;
                cartProducts.type = item.type;
                cartProducts.weight = goodsWeight;
                cartProducts.products = productInfo;
                //如果传过来了购物车数据，就算指定的购物车的数据，否则，就算全部购物车的数据
                if (ids != null && ids.Any() && ids.Contains(item.id))
                {
                    cartProducts.isSelect = true;
                }
                else
                {
                    cartProducts.isSelect = false;
                }
                //判断商品是否已收藏
                cartProducts.isCollection = await _goodsCollectionServices.Check(userId, (int)cartProducts.products.goodsId);

                cartDto.list.Add(cartProducts);
            }
            //如果不同的购物车类型，可能会做一些不同的操作。
            switch (type)
            {
                case (int)GlobalEnumVars.OrderType.Common:
                    //标准模式不需要修改订单数据和商品数据
                    break;
                case (int)GlobalEnumVars.OrderType.PinTuan:
                    //拼团模式走拼团价，去修改商品价格
                    var result = _pinTuanRuleServices.PinTuanInfo(cartDto.list);
                    if (result.status)
                    {
                        cartDto.list = result.data as List<CartProducts>;
                    }
                    else
                    {
                        return result;
                    }
                    break;
                case (int)GlobalEnumVars.OrderType.Group:
                    //团购模式不需要修改订单数据和商品数据
                    break;
                case (int)GlobalEnumVars.OrderType.Skill:
                    //秒杀模式不需要修改订单数据和商品数据
                    break;
                case (int)GlobalEnumVars.OrderType.Bargain:
                    //砍价模式

                    break;
                case (int)GlobalEnumVars.OrderType.Solitaire:
                    //接龙模式，去获取接龙商品价格。
                    break;
                case (int)GlobalEnumVars.OrderType.Meeting:
                    //订货会需要干啥？
                    break;

                default:
                    jm.msg = GlobalErrorCodeVars.Code10000;
                    return jm;
            }

            jm.status = true;
            jm.data = cartDto;
            jm.msg = GlobalConstVars.GetDataSuccess;

            return jm;
        }

        #endregion

        #region 获取处理后的购物车信息
    
   
        #region 各种计算金额

        private async Task<decimal> CalcGoodsAmount(List<CoreCmsCart> carts)
        {
            var typegroup = carts.GroupBy(m => m.type);
            decimal goodsAmount = 0;
            foreach (var item in typegroup)
            {
                switch ((OrderType)item.Key)
                {
                    case OrderType.Meeting: //订货会价格查询

                        goodsAmount += item.Where(m => m.isSelect).Sum(m => m.product.price * m.nums);
                        break;
                    default: //其他的都按普通计算
                       goodsAmount += item.Where(m=>m.isSelect).Sum(m => m.product.price * m.nums  );
                        break;
                }
            }
            return goodsAmount;
        }
     

       
        /// <summary>
        /// 运费计算
        /// </summary>
        /// <returns></returns>
        private async Task<Cost> CostFreight(List<CoreCmsCart> carts,int areaId,int freightId)
        {
            using var container = _serviceProvider.CreateScope();
            var shipServices = container.ServiceProvider.GetService<ICoreCmsShipServices>();
            var weight = carts.Sum(m => m.product.weight * m.nums);
            var yunfei = new Cost()
            {
                name = "运费",
                list = new List<CostItem>(),

            };

            var ships = await shipServices.QueryListByClauseAsync(m => m.status == 1);
            foreach (var item in ships)
            {
                yunfei.list.Add(new CostItem()
                {
                    id = item.id,
                    amount = item.isfreePostage ? 0 : CartFreight(weight, 0, areaId),
                    showName = item.name,
                });
            }


            if (freightId == 0)
            {
                yunfei.select = yunfei.list[0];
            }
            else

            {
                yunfei.select = yunfei.list.First(m => m.id == freightId);
            }

            return yunfei;
        }

        /// <summary>
        /// 包装费
        /// </summary>
        /// <param name="carts"></param>
        /// <param name="packageId"></param>
        /// <returns></returns>
        private async Task<Cost> CostPackage(List<CoreCmsCart> carts, int packageId)
        {
            var amount = carts.Sum(m => m.goods.packageCost * m.nums);
            var baozf = new Cost()
            {
                name = "包装费",
                list = new List<CostItem>(),

            };
            baozf.list.Add(new CostItem()
            {
                id = 1,
                amount = amount,
                showName = "厂家默认",
            });
            baozf.list.Add(new CostItem()
            {


                id = 2,
                amount = 0,
                showName = "无包装",
            });
            if (packageId == 0)
            {
                baozf.select = baozf.list[0];
            }
            else
            {
                baozf.select = baozf.list.First(m => m.id == packageId);
            }

          return baozf;

        }

        #endregion

        #region 各种检测
        /// <summary>
        /// 检查起订量
        /// </summary>
        /// <returns></returns>
        private async Task<bool> CheckMinimum(OrderType cartTypes, int objectId, List<CoreCmsCart> checkitems,
            ICoreShopOrderMeetingGoodsServices meetingGoodsServices, 
            ICoreCmsGoodsServices _goodsServices)
        {
            int goodsid = checkitems.First().goodsId;
            switch (cartTypes)
            {
                case GlobalEnumVars.OrderType.Meeting:
                    //订货会获取
                    var metgood = await meetingGoodsServices.QueryByClauseAsync(m => m.meetingid == objectId && m.goodid == goodsid);
                    if (checkitems.Sum(m => m.nums) < metgood.meetingminimum)
                    {

                        return false;
                    }

                    break;
                default:
                    var goods = await _goodsServices.QueryByClauseAsync(m => m.id == goodsid);
                    if (checkitems.Sum(m => m.nums) < goods.minimum)
                    {
                        return false;
                    }
                    break;
            }
            return true;
        }


        private async Task<bool> CheckMinimum(OrderType cartTypes, int objectId, int goodsid, List<CartDotColorXL> checkitems,
        ICoreShopOrderMeetingGoodsServices meetingGoodsServices,
        ICoreCmsGoodsServices _goodsServices)
        {
             
            switch (cartTypes)
            {
                case GlobalEnumVars.OrderType.Meeting:
                    //订货会获取
                    var metgood = await meetingGoodsServices.QueryByClauseAsync(m => m.meetingid == objectId && m.goodid == goodsid);
                    if (checkitems.Sum(m => m.prodList.Sum(p=>p.nums)) < metgood.meetingminimum)
                    {

                        return false;
                    }

                    break;
                default:
                    var goods = await _goodsServices.QueryByClauseAsync(m => m.id == goodsid);
                    if (checkitems.Sum(m => m.prodList.Sum(p => p.nums)) < goods.minimum)
                    {
                        return false;
                    }
                    break;
            }
            return true;
        }



     


        /// <summary>
        /// 检测库存
        /// </summary>
        /// <param name="cartTypes"></param>
        /// <param name="objectId"></param>
        /// <param name="goodsid"></param>
        /// <param name="checkitems"></param>
        /// <param name="meetingGoodsServices"></param>
        /// <param name="_goodsServices"></param>
        /// <returns></returns>
        private async Task<List<FMCartAddItem>> CheckStock(List<CoreCmsCart> checkitems)
        {
            if (checkitems == null)
            {
                return null;
            }
            List<FMCartAddItem> numNotCanBuy = new List<FMCartAddItem>();

            foreach (var item in checkitems)
            {
                if (item.product.stock > 0 && item.nums > item.product.stock)
                {
                    //数量不足的，最后判断count大于一就是有不足的
                    numNotCanBuy.Add(new FMCartAddItem()
                    {
                          canBuyNum = item.product.stock,
                           id = item.id,
                            Nums= item.nums,
                             ProductId= item.product.id,
                    });
                }
            }
            return numNotCanBuy;
 
        }
        #endregion

        /// <summary>
        /// 获取处理后的购物车信息
        /// </summary>
        /// <param name="userId">用户序列</param>
        /// <param name="ids">选中的购物车商品</param>
        /// <param name="orderType">订单类型</param>
        /// <param name="areaId">收货地址id</param>
        /// <param name="point">消费的积分</param>
        /// <param name="couponCode">优惠券码</param>
        /// <param name="freeFreight">是否免运费</param>
        /// <param name="deliveryType">关联上面的是否免运费/1=快递配送（要去算运费）生成订单记录快递方式  2=门店自提（不需要计算运费）生成订单记录门店自提信息</param>
        /// <param name="objectId">关联非普通订单营销类型序列</param>
        /// <returns></returns>
        public async Task<WebApiCallBack> GetCartInfos(int userId, int[] ids, int orderType, int areaId, int point, string couponCode, bool freeFreight = false, int deliveryType = (int)GlobalEnumVars.OrderReceiptType.Logistics, int objectId = 0)
        {
            var jm = new WebApiCallBack() { methodDescription = "获取处理后的购物车信息" };
            var cartDto = new CartDto(); //必须初始化
            var cartDtoData = await GetCartDtoData(userId, ids, orderType, objectId);
            if (!cartDtoData.status)
            {
                jm.msg = "1";
                return cartDtoData;
            }
            cartDto = cartDtoData.data as CartDto;

            jm.msg = "2";

            //算订单总金额
            foreach (var item in cartDto.list)
            {
                jm.msg = "3";
                //库存不足不计算金额不可以选择
                if (item.nums > item.products.stock)
                {
                    item.isSelect = false;
                }
                //单条商品总价
                item.products.amount = Math.Round(item.nums * (decimal)item.products.price, 2);

                if (item.isSelect)
                {
                    //算订单总商品价格
                    cartDto.goodsAmount = Math.Round(cartDto.goodsAmount + item.products.amount, 2);
                    //算订单总价格
                    cartDto.amount = Math.Round(cartDto.amount + item.products.amount, 2);
                    //计算总重量
                    cartDto.weight = Math.Round(cartDto.weight + Math.Round(item.weight * item.nums, 2), 2);
                }
            }

            //门店订单，强制无运费
            //if (deliveryType == (int)GlobalEnumVars.OrderReceiptType.IntraCityService || deliveryType == (int)GlobalEnumVars.OrderReceiptType.SelfDelivery)
            //{
            //    freeFreight = true;
            //}
            //运费判断
            //if (CartFreight(cartDto, areaId, freeFreight) == false)
            //{
            //    jm.data = cartDto;
            //    jm.msg = "运费判断";
            //    return jm;
            //}
            if (freeFreight)
            {
                cartDto.costFreight = 0;
            }
            else
            {
                cartDto.costFreight = _shipServices.GetShipCost(areaId, cartDto.weight, cartDto.goodsAmount);
            }
        

            //接下来算订单促销金额,有些模式不需要计算促销信息，这里就增加判断
            if (orderType == (int)GlobalEnumVars.OrderType.Common)
            {
                jm.data = await _promotionServices.ToPromotion(cartDto);
                jm.msg = "订单促销金额计算";
            }
            else if ((orderType == (int)GlobalEnumVars.OrderType.Group || orderType == (int)GlobalEnumVars.OrderType.Skill) && objectId > 0)
            {
                //团购秒杀默认时间过期后，不可以下单
                var dt = DateTime.Now;
                var promotionInfo = await _promotionServices.QueryByClauseAsync(p => p.startTime < dt && p.endTime > dt && p.id == objectId);

                var checkRes = await _promotionServices.SetPromotion(promotionInfo, cartDto);
                if (checkRes == false)
                {
                    jm.msg = GlobalErrorCodeVars.Code15600;
                    return jm;
                }
            }
            else if (orderType == (int)GlobalEnumVars.OrderType.PinTuan)
            {
                jm.data = await _promotionServices.ToPromotion(cartDto);
                jm.msg = "拼团也计算促销信息";
            }
            //使用优惠券，判断优惠券是否可用
            //var bl = await CartCoupon(cartDto, couponCode);
            //if (bl == false)
            //{
            //    jm.status = false;
            //    jm.data = cartDto.error.data;
            //    jm.msg = cartDto.error.msg;
            //    return jm;
            //}
            //使用积分
        //    var pointDto = await CartPoint(cartDto, userId, point);
            //if (pointDto.status == false)
            //{
            //    jm.status = false;
            //    jm.msg = pointDto.msg;
            //    return jm;
            //}

            jm.status = true;
            jm.data = cartDto;
            jm.msg = "4";

            return jm;
        }


     
        #endregion

        #region 算运费
        /// <summary>
        /// 算运费
        /// </summary>
        /// <param name="cartDto">购物车信息</param>
        /// <param name="areaId">收货地址id</param>
        /// <param name="freeFreight">是否包邮，默认false</param>
        /// <returns></returns>
        public bool CartFreight(CartDto cartDto, int areaId, bool freeFreight = false)
        {
            if (freeFreight == false)
            {
                if (areaId > 0)
                {
                    cartDto.costFreight = _shipServices.GetShipCost(areaId, cartDto.weight, cartDto.goodsAmount);
                    cartDto.amount = Math.Round(cartDto.amount + cartDto.costFreight, 2);
                }
            }
            return true;
        }

        public decimal CartFreight( decimal weight,decimal goodsAmount, int areaId)
        {
            return _shipServices.GetShipCost(areaId, weight, goodsAmount);
        }


        #endregion

        #region 购物车中使用优惠券

        /// <summary>
        /// 购物车中使用优惠券
        /// </summary>
        /// <param name="cartDto"></param>
        /// <param name="couponCode"></param>
        /// <returns></returns>
        public async Task<bool> CartCoupon(CartDto cartDto, string couponCode)
        {
            if (!string.IsNullOrEmpty(couponCode))
            {
                var arr = couponCode.Split(",");
                //判断优惠券是否可用
                var couponInfo = await _couponServices.CodeToInfo(arr, true);
                if (couponInfo.status == false)
                {
                    cartDto.error = couponInfo;
                    return false;
                }
                //判断优惠券是否符合规格
                var res = await _promotionServices.ToCoupon(cartDto, couponInfo.data as List<CoreCmsPromotion>);
                if (res.status == false)
                {
                    cartDto.error = res;
                    return false;
                }
            }
            return true;
        }

        #endregion

        #region 购物车中使用积分

        /// <summary>
        /// 购物车中使用积分
        /// </summary>
        /// <param name="cartDto"></param>
        /// <param name="userId"></param>
        /// <param name="point"></param>
        /// <returns></returns>
        public async Task<WebApiCallBack> CartPoint(CartDto cartDto, int userId, int point)
        {
            var jm = new WebApiCallBack() { status = true };
            if (point != 0)
            {
                var getUserPointDto = await _userServices.GetUserPoint(userId, 0);
                if (getUserPointDto.point < point)
                {
                    jm.status = false;
                    jm.msg = "积分不足，无法使用积分";
                    return jm;
                }
                //判断积分值多少钱
                //计算可用积分

                var allConfigs = await _settingServices.GetConfigDictionaries();

                var ordersPointProportion = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.OrdersPointProportion).ObjectToInt(10);//订单积分使用比例
                var maxPointDeductedMoney = Math.Round(cartDto.amount * ordersPointProportion / 100, 2); //最大积分抵扣的钱
                var pointDiscountedProportion = CommonHelper.GetConfigDictionary(allConfigs, SystemSettingConstVars.PointDiscountedProportion).ObjectToInt(100); //积分兑换比例
                var pointDeductedMoney = point / pointDiscountedProportion; //积分可以抵扣的钱

                if (maxPointDeductedMoney < pointDeductedMoney)
                {
                    jm.status = false;
                    jm.msg = "积分超过订单可使用的积分数量";
                    return jm;
                }
                cartDto.point = point;
                cartDto.pointExchangeMoney = pointDeductedMoney;
                cartDto.amount -= pointDeductedMoney;
            }
            jm.data = cartDto;
            return jm;
        }

        #endregion

        #region 获取购物车用户数据总数
        /// <summary>
        ///     获取购物车用户数据总数
        /// </summary>
        /// <returns></returns>
        public async Task<int> GetCountAsync(int userId)
        {
            return await _dal.GetCountAsync(userId);
        }

        #endregion


        #region 根据提交的数据判断哪些购物券可以使用
        /// <summary>
        /// 根据提交的数据判断哪些购物券可以使用
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="ids"></param>
        /// <returns></returns>
        public async Task<WebApiCallBack> GetCartAvailableCoupon(int userId, int[] ids = null)
        {
            var jm = new WebApiCallBack();
            var dt = DateTime.Now;
            var resultData = new List<CoreCmsCoupon>();

            //取用户数据，如果用户没登录，都没意义。
            var user = await _userServices.QueryByClauseAsync(p => p.id == userId);
            if (user == null)
            {
                return jm;
            }
            //先取购物车数据，如果购物车都没存购货品数据，优惠券就没意义
            //获取货品数据
            var carts = await _dal.QueryListByClauseAsync(p => p.userId == userId && p.type == (int)GlobalEnumVars.OrderType.Common);
            if (!carts.Any())
            {
                return jm;
            }
            var productIds = carts.Select(p => p.productId).ToList();
            var products = await _productsServices.QueryListByClauseAsync(p => productIds.Contains(p.id));
            if (!products.Any())
            {
                return jm;
            }
            var cartProducts = new List<CartProducts>();
            var goodIds = new List<int>();
            foreach (var item in carts)
            {
                var cp = new CartProducts { products = products.Find(p => p.id == item.productId) };
                if (cp.products == null)
                {
                    continue;
                }
                //开始赋值
                cp.id = item.id;
                cp.userId = userId;
                cp.productId = item.productId;
                cp.nums = item.nums;
                cp.type = item.type;
                //如果传过来了购物车数据，就算指定的购物车的数据，否则，就算全部购物车的数据
                if (ids != null && ids.Any())
                {
                    if (ids.Contains(item.id))
                    {
                        goodIds.Add(cp.products.goodsId);
                        cartProducts.Add(cp);
                    }
                    continue;
                }
                goodIds.Add(cp.products.goodsId);
                cartProducts.Add(cp);
            }
            //如果获取赛选后没了，就返回无
            if (!cartProducts.Any()) return jm;
            //获取商品数据
            var goods = await _goodsServices.QueryListByClauseAsync(p => goodIds.Contains(p.id));
            //如果商品都被已下架或者删除，也没了。
            if (!goods.Any()) return jm;

            cartProducts.ForEach(p =>
            {
                p.good = goods.Find(g => g.id == p.products.goodsId);
            });


            //获取我的可用优惠券
            var wherec = PredicateBuilder.True<CoreCmsCoupon>();
            wherec = wherec.And(p => p.userId == userId);
            wherec = wherec.And(p => p.isUsed == false);
            wherec = wherec.And(p => p.endTime > dt);
            var userCoupon = await _couponServices.QueryPageMapperAsync(wherec, p => p.createTime, OrderByType.Desc, false);
            if (!userCoupon.Any())
            {
                return jm;
            }

            //获取所有商品分类
            var goodsCategories = await _goodsCategoryServices.GetCaChe();

            foreach (var coupon in userCoupon)
            {
                if (coupon.promotion == null)
                {
                    continue;
                }

                //先判断优惠券是否可以使用
                //判断规则是否开启
                if (coupon.promotion.isEnable == false) continue;
                //判断优惠券规则是否到达开始时间
                if (coupon.startTime > dt) continue;
                //判断优惠券规则是否已经到结束时间了，也就是是否过期了
                if (coupon.endTime < dt) continue;

                //再来判断是否符合规格
                //判断是哪个规则，并且确认是否符合|只要有一个规则不满足，就失效。
                var type = 0;
                foreach (var pc in coupon.conditions)
                {
                    type = 0;
                    JObject parameters = (JObject)JsonConvert.DeserializeObject(pc.parameters);
                    if (parameters == null) break;
                    var objNums = 0;
                    switch (pc.code)
                    {
                        case "GOODS_ALL":
                            //只要购物车有商品就支持，因为是购物车付款调用接口，所以不存在无商品情况
                            type = 2;
                            break;
                        case "GOODS_IDS":
                            //指定某些商品满足条件
                            if (!parameters.ContainsKey("goodsId") || !parameters.ContainsKey("nums")) break;
                            objNums = parameters["nums"].ObjectToInt(0);
                            var goodsIds = CommonHelper.StringToIntArray(parameters["goodsId"].ObjectToString());
                            //只要有一个商品支持，此优惠券就可以使用。
                            if (goodsIds.Any())
                            {
                                foreach (var p in cartProducts)
                                {
                                    if (!goodsIds.Contains(p.products.goodsId))
                                    {
                                        continue;
                                    }
                                    if (p.nums >= objNums)
                                    {
                                        type = 2;
                                        break;
                                    }
                                }
                            }
                            break;
                        case "GOODS_CATS":
                            //指定商品是否满足分类
                            if (!parameters.ContainsKey("catId") || !parameters.ContainsKey("nums")) break;
                            var objCatId = parameters["catId"].ObjectToInt(0);
                            objNums = parameters["nums"].ObjectToInt(0);

                            foreach (var product in cartProducts)
                            {
                                type = _goodsCategoryServices.IsHave(goodsCategories, objCatId, product.good.goodsCategoryId) ? product.nums >= objNums ? 2 : 1
                                    : 0;
                                if (type == 2)
                                {
                                    break;
                                }
                            }
                            break;
                        case "GOODS_BRANDS":
                            //指定商品品牌满足条件
                            if (!parameters.ContainsKey("brandId") || !parameters.ContainsKey("nums")) break;
                            var objBrandId = parameters["brandId"].ObjectToInt(0);
                            objNums = parameters["nums"].ObjectToInt(0);

                            foreach (var product in cartProducts)
                            {
                                type = product.good.brandId == objBrandId ? product.nums >= objNums ? 2 : 1 : 0;
                                if (type == 2)
                                {
                                    break;
                                }
                            }
                            break;
                        case "ORDER_FULL":
                            //订单满XX金额满足条件
                            if (!parameters.ContainsKey("money")) break;
                            var objMoney = parameters["money"].ObjectToDecimal();
                            //算订单总商品价格
                            decimal goodsAmount = 0;
                            foreach (var product in cartProducts)
                            {
                                var money = product.products.price * product.nums;
                                goodsAmount += Math.Round(goodsAmount + money, 2);
                            }
                            if (goodsAmount >= objMoney)
                            {
                                type = 2;
                            }
                            break;
                        case "USER_GRADE":
                            //用户符合指定等级
                            if (!parameters.ContainsKey("grades")) break;
                            var arr = CommonHelper.StringToIntArray(parameters["grades"].ObjectToString());
                            if (arr.Contains(user.grade))
                            {
                                type = 2;
                            }
                            break;
                        default:
                            break;
                    }
                    //不满足条件，直接跳过
                    if (type != 2)
                    {
                        break;
                    }
                }

                if (type == 2)
                {
                    resultData.Add(coupon);
                }
            }

            //结果集拼装
            var resutlList = new List<GetMyCouponResultDto>();
            if (resultData != null && resultData.Any())
            {
                foreach (var item in resultData)
                {
                    var expression1 = string.Empty;
                    var expression2 = string.Empty;

                    foreach (var condition in item.conditions)
                    {
                        expression1 += PromotionHelper.GetConditionMsg(condition.code, condition.parameters);
                    }
                    foreach (var result in item.results)
                    {
                        expression2 += PromotionHelper.GetResultMsg(result.code, result.parameters);
                    }

                    var dto = new GetMyCouponResultDto
                    {
                        couponCode = item.couponCode,
                        promotionId = item.promotionId,
                        isUsed = item.isUsed,
                        userId = item.userId,
                        usedId = item.usedId,
                        createTime = item.createTime,
                        updateTime = item.updateTime,
                        couponName = item.promotion.name,
                        expression1 = expression1,
                        expression2 = expression2,
                        isExpire = item.endTime > dt,
                        startTime = item.startTime,
                        endTime = item.endTime,
                        stime = item.startTime.ToString("yyyy-MM-dd"),
                        etime = item.endTime.ToString("yyyy-MM-dd")
                    };

                    resutlList.Add(dto);
                }
            }
            jm.status = true;
            jm.data = new
            {
                list = resutlList,
                changeData = resultData,
                cartProducts,
                user
            };
            //jm.otherData = userCoupon;
            return jm;
        }

        #endregion

    }
}
